// Keywords: multispecies, interaction

species all initialize() {
	defineConstant("K", 100);
	defineConstant("R", log(20));
	defineConstant("A", 0.015);
	defineConstant("S", 10^2);    // larger is more stable, but slower
	defineConstant("N0_host", asInteger((135.6217 + 0.01) * S));
	defineConstant("N0_parasitoid", asInteger((109.3010 + 0.01) * S));
	
	initializeSLiMModelType("nonWF");
}
species host initialize() {
	initializeSpecies(avatar="🐛", color="cornflowerblue");
	// tag values in host are unused
}
species parasitoid initialize() {
	initializeSpecies(avatar="🦟", color="red");
	// tag values in parasitoid count successful hunts
}

species host reproduction() {
	// reproduce each host with a mean of exp(r) offspring
	litterSize = rpois(1, exp(R));
	
	if (litterSize > 0)
	{
		mate = subpop.sampleIndividuals(1, exclude=individual);
		for (i in seqLen(litterSize))
			subpop.addCrossed(individual, mate);
	}
}
species parasitoid reproduction() {
	// reproduce each parasitoid as many times as it parasitized
	litterSize = individual.tag;
	
	if (litterSize > 0)
	{
		mate = subpop.sampleIndividuals(1, exclude=individual);
		for (i in seqLen(litterSize))
			subpop.addCrossed(individual, mate);
	}
}

ticks all 1 early() {
	host.addSubpop("p1", N0_host);
	parasitoid.addSubpop("p2", N0_parasitoid);
}

ticks all early()
{
	hosts = host.subpopulations.individuals;
	parasitoids  = parasitoid.subpopulations.individuals;
	
	// first, kill off the parental generation
	host_age = hosts.age;
	hosts[host_age > 0].fitnessScaling = 0.0;
	
	parasitoid_age = parasitoids.age;
	parasitoids[parasitoid_age > 0].fitnessScaling = 0.0;
	
	// narrow down to the juveniles and assess densities
	hosts = hosts[host_age == 0];
	parasitoids = parasitoids[parasitoid_age == 0];
	
	x1 = hosts.size() / S;          // host density
	x2 = parasitoids.size() / S;    // parasitoid density
	
	// next, hunt; each parasitoid counts its successes
	parasitoids.tag = 0;
	P_parasitized = 1 - exp(-A * x2);
	luck = rbinom(hosts.size(), 1, P_parasitized);
	dead = hosts[luck == 1];
	dead.fitnessScaling = 0.0;
	hunters = sample(parasitoids, dead.size(), replace=T);
	for (hunter in hunters)
		hunter.tag = hunter.tag + 1;
	hosts = hosts[luck == 0];
	
	// finally, competition kills a fraction of survivors
	// this is based on pre-parasitism density
	P_survives = exp(-x1 / K);
	luck = rbinom(hosts.size(), 1, P_survives);
	dead = hosts[luck == 0];
	dead.fitnessScaling = 0.0;
}

ticks all 250 late() {
}
